package com.example.base_model.work

import android.content.Context
import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.example.base_model.work.task.CleanupDbWorker
import com.example.base_model.work.task.DataSyncWorker
import com.example.base_model.work.task.LogUploadWorker
import com.example.base_model.work.task.PreloadCacheWorker
import java.util.concurrent.TimeUnit

/**
 * @Author jiangKunKun
 * @CreateDate 2025/8/19
 * @Description 任务调度
 * @SpittingGrooves
 */
object WorkScheduler {
    /**
     * 通用后台任务约束
     * 共用约束：仅在 Wi-Fi、充电、空闲时执行（省电关键）
     */
    private fun getBackgroundConstraints() = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.UNMETERED)     // 设置网络类型为无计量网络，即Wi-Fi（可根据需求改为CONNECTED，表示任何网络）
        .setRequiresCharging(true)                       // 要求设备充电时执行
        .setRequiresDeviceIdle(true)                     // 要求设备空闲时执行（在Doze模式下效果更佳）
        .setRequiresBatteryNotLow(true)                  // 要求电量不低于设定阈值时执行
        .build()

    /**
     * 日志上传：每小时一次
     */
    fun scheduleLogUpload(context: Context) {
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED)     // 推荐Wi-Fi上传，节省用户流量
            .setRequiresCharging(true)                       // 充电时上传，节省电量
            .setRequiresBatteryNotLow(true)                  // 电量充足时执行
            .build()

        // 创建周期性工作请求，每小时重复一次，并在每小时的最后15分钟内弹性执行
        val work = PeriodicWorkRequestBuilder<LogUploadWorker>(
            1, TimeUnit.HOURS, // repeatInterval: 每小时重复
            15, TimeUnit.MINUTES  // flexInterval: 在每小时的最后15分钟内执行
        )
            .setConstraints(constraints) // 设置任务约束条件
            .addTag("log_upload")        // 添加标签，用于查询或取消任务
            .build()

        // 将任务加入WorkManager队列，如果存在同名任务，则保持现有任务
        WorkManager.getInstance(context)
            .enqueueUniquePeriodicWork(
                "log_upload_work",          // 唯一任务名称
                ExistingPeriodicWorkPolicy.KEEP, // 策略：如果任务已存在，则保留现有任务
                work
            )
    }

    /**
     * 数据同步：每天一次
     */
    fun scheduleDataSync(context: Context) {
        // 创建周期性工作请求，每24小时重复一次
        val work = PeriodicWorkRequestBuilder<DataSyncWorker>(24, TimeUnit.HOURS)
            .setConstraints(getBackgroundConstraints()) // 使用通用后台任务约束
            .addTag("data_sync")                        // 添加标签
            .build()

        // 将任务加入WorkManager队列，如果存在同名任务，则替换为新任务
        WorkManager.getInstance(context)
            .enqueueUniquePeriodicWork(
                "data_sync_work",          // 唯一任务名称
                ExistingPeriodicWorkPolicy.REPLACE, // 策略：如果任务已存在，则替换为新任务
                work
            )
    }

    /**
     * 缓存预加载：每天一次（夜间）
     */
    fun scheduleCachePreload(context: Context) {
        // 创建周期性工作请求，每24小时重复一次
        val work = PeriodicWorkRequestBuilder<PreloadCacheWorker>(24, TimeUnit.HOURS)
            .setConstraints(getBackgroundConstraints()) // 使用通用后台任务约束
            .addTag("cache_preload")                    // 添加标签
            .build()

        // 将任务加入WorkManager队列，如果存在同名任务，则保持现有任务
        WorkManager.getInstance(context)
            .enqueueUniquePeriodicWork(
                "cache_preload_work",      // 唯一任务名称
                ExistingPeriodicWorkPolicy.KEEP, // 策略：如果任务已存在，则保留现有任务
                work
            )
    }

    /**
     * 数据库清理：每周一次
     */
    fun scheduleDbCleanup(context: Context) {
        // 创建周期性工作请求，每7天重复一次
        val work = PeriodicWorkRequestBuilder<CleanupDbWorker>(7, TimeUnit.DAYS)
            .setConstraints(
                Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.CONNECTED) // 有网络即可（不限制Wi-Fi）
                    .setRequiresBatteryNotLow(true)              // 电量充足时执行
                    .build()
            )
            .addTag("db_cleanup")                               // 添加标签
            .build()

        // 将任务加入WorkManager队列，如果存在同名任务，则保持现有任务
        WorkManager.getInstance(context)
            .enqueueUniquePeriodicWork(
                "db_cleanup_work",         // 唯一任务名称
                ExistingPeriodicWorkPolicy.KEEP, // 策略：如果任务已存在，则保留现有任务
                work
            )
    }

    /**
     * 取消所有任务（调试或用户退出登录时）
     */
    fun cancelAllWorks(context: Context) {
        // 取消所有已入队或正在运行的任务
        WorkManager.getInstance(context).cancelAllWork()
    }

    /**
     * 例子 点击事件使用：用于演示一次性任务的调度
     */
    fun scheduleExample(context: Context) {
        // 创建一次性工作请求，用于演示目的
        val work = OneTimeWorkRequestBuilder<DataSyncWorker>()
            .setConstraints(
                Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.CONNECTED) // 只要有网络连接即可执行
                    .build()
            )
            .build()

        // 将一次性任务加入WorkManager队列
        WorkManager.getInstance(context).enqueue(work)
    }
}